package com.klun.concTrueWar.seven;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.*;

/**
 * 向 LogWriter 添加可靠的取消操作
 */
public class LogService {
    private final BlockingQueue<String> queue;
    private final LoggerThread loggerThread;
    private final PrintWriter writer;
    private boolean isShutdown;
    private int reservations;

    public LogService(BlockingQueue<String> queue, LoggerThread loggerThread, PrintWriter writer) {
        this.queue = queue;
        this.loggerThread = loggerThread;
        this.writer = writer;
    }

    public void start(){
        loggerThread.start();
    }
    public void stop(){
        synchronized (this){
            isShutdown = true;
        }
        // 给线程中断信号
        loggerThread.interrupt();
    }
    public void log(String msg) throws InterruptedException {
        synchronized (this){
            if (isShutdown){
                throw new IllegalStateException();
            }
            ++reservations;
        }
        queue.put(msg);
    }
    private class LoggerThread extends Thread{
        @Override
        public void run() {
            try{
                while (true){
                    try{
                        //  类上加锁
                        synchronized (LogService.this){
                            if(isShutdown && reservations == 0){
                                break;
                            }
                            String msg = queue.take();
                            synchronized (LogService.this){
                                --reservations;
                            }
                            writer.print(msg);
                        }
                    } catch (InterruptedException e) {
                        // 重新尝试
                        e.printStackTrace();
                    }

                }
            }finally {
                writer.close();
            }
        }
    }
    class RunTest {
        public void main(String[] args) throws ExecutionException, InterruptedException {
            ArrayList<Callable<String>> list = new ArrayList<>();
            // 添加两个任务，一个有异常处理，一个没有异常处理
            ExecutorService executor = Executors.newCachedThreadPool();
            //  list 元素实现了callAble的集合
            String getValueA = executor.invokeAny(list);
            System.out.println("zzz " + getValueA);
            executor.shutdown();
        }
    }
}
